/**
 * 
 */
package com.leehom.arch.storage.config;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.alibaba.datax.common.util.Configuration;
import com.aliyun.oss.ClientBuilderConfiguration;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.comm.Protocol;
import com.leehom.arch.storage.exception.FileStorageException;
import com.leehom.arch.storage.exception.MessageCode;
import com.leehom.arch.storage.handler.FileStorageHandler;
import com.leehom.arch.storage.handler.LocalFileStorageHandler;
import com.leehom.arch.storage.handler.MinIOFileStorageHandler;
import com.leehom.arch.storage.model.Storage;
import com.leehom.arch.storage.service.FileService;
import com.leehom.arch.storage.service.FileServiceRepository;
import com.leehom.arch.storage.service.impl.FileServiceImpl;

import io.minio.MinioClient;

/**
 * @类名: FileStorageBeanConfiguration
 * @说明: 文件存储bean配置
 *
 * @author leehom
 * @Date 2019年10月8日 下午4:21:34 修改记录：
 *
 * @see
 */
public class FileStorageBeanConfiguration {

    public final static String CONFIG_KEY_STORAGE = "storage";
    public final static String CONFIG_KEY_STORAGE_CLIENT = "client";
    
	// 文件服务库，单例
	private volatile static FileServiceRepository serviceRepository;
	public static FileServiceRepository serviceRepository(Configuration config) {
		if(serviceRepository==null) {
			synchronized (FileServiceRepository.class) {
				if(serviceRepository==null) {
					serviceRepository = new FileServiceRepository();
					// 
					Map<String, FileService> serviceMap = new HashMap<>();
					// 构建存储，
					List<Configuration> storageConfigs = config.getListConfiguration(CONFIG_KEY_STORAGE);
					for(Configuration c : storageConfigs)  {
						Storage storage = storage(c);
						// 每个存储对应一个文件服务
						FileServiceImpl fs = new FileServiceImpl();
						fs.setStorage(storage);
						//
						FileStorageHandler handler = fileStorageHandler(storage.getSchema(), c.getConfiguration(CONFIG_KEY_STORAGE_CLIENT));
						fs.setHandler(handler);
						serviceMap.put(storage.getRootUrl(), fs);
					}
					serviceRepository.setServices(serviceMap);
				}
			}
		}
		return serviceRepository;
		
	}
	
	// 存储
	private static Storage storage(Configuration config) {
        Storage storage = new Storage();
        storage.setName(Key.storageName(config));
        storage.setRootUrl(Key.rootUrl(config));
        storage.setDescription(Key.storageDescription(config));
        return storage;
	}
	
	// 载入handler
	private static FileStorageHandler fileStorageHandler(String schema, Configuration clientConfig) {
		if(schema.equals("minio"))
			return minioFileStorageHandler(clientConfig);
		if(schema.equals("local"))
			return localFileStorageHandler();
		throw new FileStorageException(MessageCode.ERROR_STORAGE_UNKNOWNSCHEMA, schema);
	}
	
	private static FileStorageHandler localFileStorageHandler() {
		LocalFileStorageHandler h = new LocalFileStorageHandler();
		return h;
	}
	
	private static FileStorageHandler minioFileStorageHandler(Configuration clientConfig) {
		MinioClient client = minioClient(clientConfig);
		MinIOFileStorageHandler h = new MinIOFileStorageHandler();
		h.setMinioClient(client);
		return h;
	}
	
	// client
    // minio client
    private static MinioClient minioClient(Configuration config) {
        MinioClient minioClient = MinioClient.builder().
        		endpoint(Key.minioUrl(config)).
        		credentials(Key.minioAccessKey(config), Key.minioSecretKey(config)).
        		build();
        return minioClient;
    }
    
	// oss client
    private static OSS ossClient(AliOssProperties props) {
		ClientBuilderConfiguration conf = new ClientBuilderConfiguration();
		conf.setProtocol(Protocol.HTTPS);
		OSS ossClient = new OSSClientBuilder().build(props.getEndpoint(), 
				props.getAccessKeyId(), props.getAccessKeySecret(), conf);
		return ossClient;
	}

}
